<template>
  <el-dialog
      :model-value="visible"
      @update:model-value="v=>$emit('update:visible',v)"
      title="图片选择"
      :modal="false"
      width="80%">
    <div class="flex-row p_x10 p_y10">
      <div class="sidebar" v-loading="cateLoading">
        <el-tree :data="cate"
                 class="no-select"
                 :props="{children: 'children',label:'name'}"
                 :render-content="renderContent"
                 empty-text="" @node-click="onCateCheck"
                 :check-on-click-node="true"></el-tree>
      </div>
      <div class="content flex-column">
        <div class="p_x15">
          <el-button-group>
            <el-button :type="isEditCate?'warning':'primary'" size="mini"
                       @click.stop="isEditCate=!isEditCate">
              {{ isEditCate ? '取消分类编辑' : '编辑分类' }}
            </el-button>

            <el-button class="picture-manager-upload" type="primary" size="mini">
              <el-upload
                  class="upload-demo"
                  ref="upload"
                  name="url"
                  :show-file-list="false"
                  action=""
                  :before-upload="onUpload">
                上传图片
              </el-upload>
            </el-button>
            <el-button type="warning" size="mini" :disabled="!checkIds.length"
                       @click="isSwitchCate=true;cateEditVisible=true">移动分类
            </el-button>
            <el-button type="danger" size="mini" :disabled="!checkIds.length"
                       @click.stop="onPictureRemove(checkIds)">
              删除图片
            </el-button>
          </el-button-group>
        </div>
        <div class="flex flex-wrap content-images p_x10 p_y5" v-loading="loading">
          <template v-if="pictures.data&&pictures.data.length">
            <div :class="{'content-images-item':true, checked:checkIds.indexOf(item.id)>=0}"
                 v-for="(item,index) of pictures.data">
              <span class="identifier">{{ checkIds.indexOf(item.id) + 1 }}</span>
              <el-image :preview-src-list="srcList"
                        ref="imageItem"
                        class="picture-manager"
                        style="width: 100px;height: 100px"
                        :src="item.url" fit="scale-down"></el-image>
              <div class="image-overlay flex-row justify-end"
                   @click="onCheck(item.id)">
                                <span class="image-overlay-tool-item">
                                    <i class="el-icon-view font20" @click.stop="onShowViewer(index)"
                                       style="color: #ffffff;"></i>
                                </span>
                <span class="image-overlay-tool-item" style="background-color: #f56c6c">
                                    <i class="el-icon-delete font20" @click.stop="onPictureRemove(item.id)"
                                       style="color: #ffffff;"></i>
                                 </span>
              </div>
            </div>
          </template>
          <div class="no-data" style="line-height: 200px" v-else>暂无图片</div>
        </div>
        <el-pagination
            :current-page="pictures.current_page"
            :page-size.sync="pageSize"
            @current-change="initLists"
            layout="total, sizes, prev, pager, next"
            class="p_l20"
            :total="pictures.total">
        </el-pagination>
        <div class="p_x15 flex-row justify-between">
          <el-button-group>
            <el-button type="primary" size="mini" :disabled="!checkIds.length"
                       @click="onUsed" class="m_y2">
              使用选中图片
            </el-button>
            <el-button :type="isEditStatus?'warning':'primary'" size="mini"
                       @click="isEditStatus=!isEditStatus" class="m_y2">
              进入/取消编辑
            </el-button>
            <el-button :type="checkIds.length?'warning':'primary'" size="mini" @click="onSelectAll" class="m_y2">
              全选/取消图片
            </el-button>

          </el-button-group>
        </div>

      </div>

      <!--分类编辑start-->
      <el-dialog
          :visible.sync="cateEditVisible"
          :modal="false"
          width="50%">
        <el-form :model="cateForm" label-width="80px">
          <el-form-item label="父类">
            <el-cascader
                class="no-select"
                placeholder="父级分类"
                v-model="cateForm.pid"
                :props="{label:'name',value:'id',children:'children',checkStrictly:true,expandTrigger: 'hover'}"
                :options="cateOptional"></el-cascader>
          </el-form-item>
          <el-form-item label="分类名称" v-if="!isSwitchCate">
            <el-input v-model="cateForm.name" placeholder="分类名称"></el-input>
          </el-form-item>
        </el-form>
        <span slot="footer">
                <el-button @click="cateEditVisible = false">取 消</el-button>
                <el-button type="primary" @click="onCateAdd" v-if="isSwitchCate">移动到分类</el-button>
                <el-button type="primary" @click="onCateAdd" v-else-if="cateForm.id">编 辑</el-button>
                <el-button type="primary" @click="onCateAdd" v-else>添 加</el-button>
              </span>
      </el-dialog>
      <!--分类编辑end-->
    </div>
  </el-dialog>
</template>

<script>
import {http} from '../../api/http'
import {resources} from '../../api/modules/resources'
import TOperation from '../TableCol/TOperation'
import {Toast, ToastBox} from '../../utils/toast'
import {deepClone, isArray, isEmpty, isUndefined} from '../../utils/helpers'

const cateForm = {
  id: 0,
  pid: [0],
  name: ''
}
export default {
  name: 'PictureManager',
  components: {
    TOperation
  },
  props: {
    visible: {type: Boolean, default: false},
    max: {
      type: Number,
      default: Infinity
    }
  },
  data() {
    return {
      cate: [],
      cateOptional: [],
      pageSize: 20,
      currentCateId: 0,
      isEditCate: false,
      isEditStatus: false, // 编辑状态
      cateEditVisible: false,
      cateLoading: false,
      cateForm,
      loading: false,
      isSwitchCate: false,
      srcList: [],
      pictures: {},
      checkIds: [],
      disabledCateIds: []
    }
  },
  created() {
    // this.initCate()
    // this.initLists()
  },
  watch: {
    currentCateId(val) {
      this.initLists(1)
    },
    pageSize() {
      this.initLists()
    },
    visible(val) {
      if (!val) {
        this.isEditCate = false
        this.isSwitchCate = false
        this.srcList = []
        this.checkIds = []
        this.disabledCateIds = []
        this.emptyCateForm()
      }
    },
    isEditStatus(val) { // 取消编辑状态（取消所有选中）
      if (!val) this.checkIds = []
    },
    cateEditVisible(val) {
      if (!val) {
        this.isSwitchCate = false
        this.disabledCateIds = []
        this.emptyCateForm()
      }
    }
  },
  emits: ["update:visible", 'onUsed', 'onPictureRemove'],
  methods: {
    onUsed() {
      const checkIds = this.checkIds
      if (!checkIds.length) {
        return ToastBox.warning('请选择图片资源')
      }
      const urls = [], data = this.pictures.data || []
      data.forEach(item => {
        if (checkIds.includes(item.id)) {
          urls.push(item.url)
        }
      })
      this.$emit('onUsed', urls)
      this.$emit('update:visible', false)
    },
    // 初始化分类
    initCate() {
      this.cateLoading = true
      http(resources.cate).then(({data}) => {
        data = data || []
        const data2 = deepClone(data)
        data2.unshift({id: 0, name: '顶级分类'})
        data.unshift({id: 0, name: '全部分类'})
        this.cate = data
        this.cateOptional = data2
        this.cateLoading = false
      }).catch(e => {
        this.cateLoading = false
      })
    },
    // 初始化图片列表
    initLists(page) {
      if (!page) {
        page = this.pictures.current_page || 1
      }
      this.loading = true
      this.srcList = []
      this.checkIds = []
      this.disabledCateIds = []
      http(resources.lists, {page, size: this.pageSize, cate_id: this.currentCateId}).then((res) => {
        this.pictures = res
        const lists = res.data || []
        lists.forEach(item => {
          this.srcList.push(item.url)
        })
        this.loading = false
      }).catch(e => {
        this.loading = false
      })
    },
    // 点击图片
    onCheck(id) {
      const index = this.checkIds.indexOf(id)
      if (index === -1) {
        const l = this.checkIds.length
        if (!this.isEditStatus && l >= this.max) { // 非编辑状态下限定（最后一条时做特殊的替换选中处理）
          return this.checkIds.splice(l - 1, 1, id)
        }
        this.checkIds.push(id)
      } else {
        this.checkIds.splice(index, 1)
      }
    },
    // 查看大图
    onShowViewer(index) {
      const imageItem = this.$refs.imageItem[index]
      imageItem.showViewer = true
    },
    // 图片全选取消
    onSelectAll() {
      if (this.checkIds.length) {
        this.checkIds = []
      } else {
        const data = this.pictures.data || []
        data.forEach(({id}) => {
          this.onCheck(id)
        })
      }
    },
    // 删除图片
    async onPictureRemove(id) {
      if (await ToastBox.confirm('确认删除？')) {
        try {
          const {message} = await http(resources.remove, {id})
          Toast(message)
          const data = this.pictures.data || []
          let urls = []
          let _ids = isArray(id) ? id : [id]
          data.forEach(item => {
            if (_ids.indexOf(item.id)) {
              urls.push(item.url)
            }
          })
          this.$emit('onPictureRemove', urls)
          this.initLists()
        } catch (e) {

        }
      }

    },
    // 上传图片
    onUpload(file) {
      const data = new FormData
      data.append('cate_id', this.currentCateId)
      data.append('image', file)
      http(resources.add, data).then(({message}) => {
        Toast(message)
        this.initLists()
      })
      return false
    },
    // 点击分类
    onCateCheck(data, node) {
      if (this.isEditCate) {
        return false
      }
      this.currentCateId = data.id
    },
    async onCateAdd() {
      try {
        const {id, pid, name} = this.cateForm
        if (this.isSwitchCate) { // 切换分类
          const checkIds = this.checkIds
          if (isEmpty(checkIds)) {
            return ToastBox.warning('请先选择图片资源')
          }
          let cate_id = deepClone(pid).pop()
          const {message} = await http(resources.switchCate, {cate_id, id: checkIds})
          Toast(message)
          this.cateEditVisible = false
          this.initLists()
          return
        }
        if (isEmpty(name)) {
          return ToastBox.warning('请填写分类名称')
        }
        let res = {}
        let _pid = deepClone(pid).pop()
        if (id) {
          res = await http(resources.updateCate, {id, pid: _pid, name})
        } else {
          res = await http(resources.createCate, {pid: _pid, name})
        }
        Toast(res.message)
        this.cateEditVisible = false
        this.initCate()
      } catch (e) {

      }
    },
    async onCateRemove(id) {
      if (!id) {
        return ToastBox.warning('该分类不允许删除')
      }
      if (await ToastBox.confirm('确认删除？')) {
        try {
          const {message} = await http(resources.destroyCate, {id})
          Toast(message)
          if (this.currentCateId === id) {
            this.currentCateId = 0
          }
        } catch (e) {

        }
      }
    },
    emptyCateForm(data = {}) {
      if (!isUndefined(data.pid) && !isArray(data.pid)) {
        data.pid = [data.pid]
      }
      this.cateOptional = this.initDisabledCateOptional(deepClone(this.cateOptional))
      this.cateForm = Object.assign({}, cateForm, data)
    },
    initDisabledCateOptional(cateOptional, disabledCateIds, disabled = false) {
      disabledCateIds = this.disabledCateIds || disabledCateIds
      return cateOptional.map(item => {
        item.disabled = disabled || disabledCateIds.indexOf(item.id) >= 0
        if (item.disabled && item.children) {
          item.children = this.initDisabledCateOptional(item.children, disabledCateIds, true)
        } else if (item.children) {
          item.children = this.initDisabledCateOptional(item.children, disabledCateIds)
        }
        return item
      })
    },
    renderContent(h, {node, data, store}) {
      const option = this.isEditCate ? (
          <span>
              <i class="el-icon-plus font20 p_x5 text-light-green" onClick={() => {
                this.emptyCateForm()
                this.cateEditVisible = true
              }}></i>
            {data.id ? (
                <i class="el-icon-edit font20 p_x5 text-light-green" onClick={() => {
                  this.disabledCateIds = [data.id]
                  this.emptyCateForm(data)
                  this.cateEditVisible = true
                }}></i>
            ) : null}
            {data.id ? (
                <i class="el-icon-delete font20 p_x5" style="color: #f56c6c;" onClick={() => {
                  this.onCateRemove(data.id)
                }}></i>
            ) : null}
          </span>
      ) : null
      return (
          <div class="font14 flex-row justify-between" style="width:100%">
            {this.currentCateId === data.id ? (<span
                class="text-light-blue">{node.label}</span>) : (<span>{node.label}</span>)}
            <span>{option}</span>
          </div>
      )
    }
  }
}
</script>
<style lang="scss" scoped>
.sidebar {
  width: 200px;
  overflow-x: auto;
}

.content {
  width: 100%;
}

.content-images {
  width: 100%;
  min-height: 100px;
  height: auto;
}

.content-images-item {
  display: flex;
  padding: 5px;
  margin: 3px;
  position: relative;
  border: #cccccc solid 2px;
  cursor: pointer;
}

.content-images-item.checked {
  border-color: #5FB878;
}

.image-overlay {
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0;
  right: 0;
  background-color: rgba(0, 0, 0, 0);

  .image-overlay-tool-item {
    background-color: #409eff;
    border-radius: 2px;
    width: 20px;
    height: 20px;
    text-align: center;
    line-height: 20px;
    margin-left: 2px;
    margin-right: 2px;
    display: none;
  }

}

.image-overlay:hover {
  background-color: rgba(0, 0, 0, 0.2);


  .image-overlay-tool-item {
    display: inline-block;
  }

}

.content-images-item .identifier {
  z-index: 2;
  display: none;
}

.content-images-item.checked .identifier {
  position: absolute;
  display: inline-block;
  min-width: 22px;
  width: auto;
  height: 22px;
  line-height: 22px;
  text-align: center;
  color: #ffffff;
  left: -5px;
  top: -5px;
  border-radius: 2px;
  background-color: #2F4056;
}
</style>
<style>
.picture-manager.el-avatar.el-avatar--square img {
  width: 100% !important;
}

.picture-manager-upload .el-upload {
  border-width: 0;
  overflow: inherit;
}
</style>
